<script setup>
/**
 * TableView.vue - 封装ElTable的高级表格组件
 * 
 * 功能特性：
 * 1. 支持动态列配置
 * 2. 内置列显示/隐藏功能
 * 3. 支持自定义列渲染
 * 4. 集成加载状态
 * 5. 保留Element Plus表格全部功能
 */

import {
  ElTable,
  ElTableColumn,
  ElDropdown,
  ElDropdownItem,
  ElDropdownMenu,
  ElCheckbox,
  vLoading
} from 'element-plus'
import { ref, computed, defineComponent } from 'vue'
import { ArrowDown } from '@element-plus/icons-vue'

/**
 * 动态渲染组件
 * 用于处理columns中的render函数
 */
const TemplateRender = defineComponent({
  props: {
    scope: Object,    // 当前行数据
    render: Function  // 渲染函数
  },
  render(props) {
    return props.render(props.scope)
  }
})

// 组件Props定义
const props = defineProps({
  // 表格数据（必需）
  data: {
    type: Array,
    required: true,
    default: () => []
  },
  // 列配置（必需）
  columns: {
    type: Array,
    required: true,
    default: () => []
  },
  // 表格全局配置
  tableOptions: {
    type: Object,
    default: () => {}
  },
  // 列默认配置
  columnOptions: {
    type: Object,
    default: () => {}
  },
  // 加载状态
  loading: {
    type: Boolean,
    default: false
  },
  // 加载背景色
  loadingBackground: {
    type: String,
    default: ''
  },
  // 加载图标
  loadingSpinner: {
    type: String,
    default: ''
  },
  // 加载文字
  loadingText: {
    type: String,
    default: ''
  },
  // 是否启用列选择功能
  selectionColumns: {
    type: Boolean,
    default: false
  },
  // 列选择缓存名称（用于区分不同表格）
  selectionColumnsName: {
    type: String,
    default: ''
  },
  // 默认隐藏的列
  selectionHiddenColumns: {
    type: Array,
    default: () => []
  }
})

// 默认表格配置（会被props.tableOptions覆盖）
const defaultTableOptions = {
  stripe: true,                 // 斑马纹
  border: true,                 // 边框
  showOverflowTooltip: true     // 溢出显示tooltip
}

// 默认列配置（会被props.columnOptions覆盖）
const defaultColumnOptions = {
  showOverflowTooltip: true     // 溢出显示tooltip
}

const _ref = ref()              // 表格实例引用
const columnsOptions = ref([])   // 列选择器选项

/**
 * 计算属性：过滤后的列配置
 * 自动排除hidden和disappear为true的列
 */
const _columns = computed(() =>
  props.columns.filter((column) => !column.hidden && !column.disappear)
)

/**
 * 处理列显示状态变化
 * @param {Object} value - 列选项
 * @param {Boolean} $event - 是否显示
 */
const handleChange = (value, $event) => {
  value.value = $event
  props.columns.find((item) => {
    if (item.label === value.label) {
      item.hidden = !$event
    }
  })
}

// 初始化列选项（去除缓存逻辑）
columnsOptions.value = props.columns
  .filter((item) => item.label && !item.disappear)
  .map((item) => ({
    value: !props.selectionHiddenColumns.includes(item.label),
    label: item.label
  }))

// 暴露表格实例方法
defineExpose({ _ref })
</script>

<template>
  <div class="jms-table">
    <!-- 主表格 -->
    <el-table
      ref="_ref"
      v-loading="loading"
      :element-loading-background="props.loadingBackground"
      :element-loading-spinner="props.loadingSpinner"
      :element-loading-text="props.loadingText"
      :data="props.data"
      v-bind="{ ...defaultTableOptions, ...$attrs, ...props.tableOptions }"
    >
      <!-- 动态渲染列 -->
      <el-table-column
        v-for="(column, index) in _columns"
        :key="index"
        v-bind="{
          ...defaultColumnOptions,
          showOverflowTooltip: column.type !== 'selection',
          ...column
        }"
      >
        <!-- 自定义列内容 -->
        <template v-if="column.render" #default="scope">
          <TemplateRender :scope="scope" :render="column.render" />
        </template>
        
        <!-- 自定义列头 -->
        <template
          v-if="column.headerRender || (props.selectionColumns && index === _columns.length - 1)"
          #header="scope"
        >
          <TemplateRender
            v-if="column.headerRender"
            :scope="scope"
            :render="column.headerRender"
          />
          <span v-else>{{ column.label }}</span>
        </template>
      </el-table-column>
    </el-table>

    <!-- 列选择下拉菜单（右上角） -->
    <el-dropdown
      v-if="props.selectionColumns"
      :hide-on-click="false"
      size="small"
    >
      <div class="selection-columns"><ArrowDown /></div>
      <template #dropdown>
        <el-dropdown-menu>
          <el-dropdown-item v-for="item in columnsOptions" :key="item.label">
            <el-checkbox
              v-model="item.value"
              :label="item.label"
              size="small"
              @change="handleChange(item, $event)"
            />
          </el-dropdown-item>
        </el-dropdown-menu>
      </template>
    </el-dropdown>
  </div>
</template>

<style scoped>
.jms-table {
  position: relative;
}
.selection-columns {
  display: inline-flex;
  justify-content: center;
  align-items: center;
  height: 1rem;
  width: 1rem;
  border: 1px solid var(--el-border-color);
  border-radius: 4px;
  cursor: pointer;
}
</style>